<template>
  <div class="w100 h100">
    <a-layout style="height: 100%">
      <a-layout-header :style="headerStyle">
        <div
          style="display: flex; justify-content: space-between; padding: 0 10px"
        >
          <div>
            <a-space>
              <a-button size="small" @click="importXML">导入XML</a-button>
              <a-button size="small" @click="preView">预览</a-button>
              <a-button size="small" @click="moreBig">放大</a-button>
              <a-button size="small" @click="moreSmall">缩小</a-button>
              <a-button size="small" @click="reset">还原并居中</a-button>
              <a-button size="small" :disabled="!revocable" @click="processUndo"
                >撤销</a-button
              >
              <a-button size="small" :disabled="!revocable" @click="processRedo"
                >恢复</a-button
              >
              <a-button size="small" @click="processRestart">重新绘制</a-button>
              <a-button size="small" @click="exportXML">下载xml</a-button>
              <a-button size="small" @click="exportSVG">下载svg</a-button>
              <a-button
                v-if="simulation"
                size="small"
                @click="processSimulation"
                >{{ simulationStatus ? "退出模拟" : "开启模拟" }}</a-button
              >
              <a-button size="small" @click="showHideMap"
                >显示/隐藏地图</a-button
              >
            </a-space>
          </div>
          <div>
            <a-space>
              <a-button size="small" @click="cancel">取消</a-button>
              <a-button type="primary" size="small" @click="toSave"
                >保存</a-button
              >
            </a-space>
          </div>
        </div>
      </a-layout-header>
      <a-divider style="margin: 0" />
      <a-layout class="cav-container">
        <a-layout-content :style="contentStyle" @mousewheel.prevent>
          <div class="bpmn-page">
            <div
              id="modeler-container"
              ref="modelerContainer"
              class="modeler-container"
            />
          </div>
        </a-layout-content>
        <a-layout-sider
          v-if="!isReadOnly"
          class="silder-box"
          style="min-width: 300px"
        >
          <panel
            :bpmnElementId="bpmnElementId"
            :users="users"
            :roles="roles"
            :groups="groups"
            :categorys="categorys"
            :businessObject="businessObject"
            :type="type"
          />
        </a-layout-sider>
      </a-layout>
    </a-layout>
  </div>
  <!-- 查看实时生成的XML -->
  <teleport to="body">
    <a-modal
      v-model:open="xmlVisible"
      wrap-class-name="full-modal"
      width="100%"
      :footer="null"
    >
      <v-ace-editor
        v-model:value="xmlView"
        lang="xml"
        theme="chrome"
        :options="editorOptions"
        class="vue-ace-editor"
      />
    </a-modal>
  </teleport>
</template>

<script setup lang="ts">
import {
  reactive,
  ref,
  onMounted,
  onBeforeUnmount,
  nextTick,
  provide,
  watch,
} from "vue";
// 模拟流转流程
import tokenSimulation from "bpmn-js-token-simulation";
import translate from "@/components/Camunda/Bpmn/src/zh";
import Modeler from "bpmn-js/lib/Modeler";
import lintConfig from "../../../../bpmnlint.config";
import { PropertiesMap } from "@/components/Camunda/Bpmn/src/bpmn-type";
import createDefaultBpmnXml from "@/components/Camunda/Bpmn/src/defaultBpmnXml";
import defaultEseyBpmnXml from "@/components/Camunda/Bpmn/src/defaultEseyBpmnXml";
import createDefaultEmptyXml from "@/components/Camunda/Bpmn/src/defaultEmptyXml";
// 网格自适应背景
import GridLineModule from "diagram-js-grid-bg";
// 模拟流转流程样式
import "bpmn-js-token-simulation/assets/css/bpmn-js-token-simulation.css";
// BPMN编辑器样式
import "bpmn-js/dist/assets/diagram-js.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
// 小地图
import "diagram-js-minimap/assets/diagram-js-minimap.css";
import miniMapModule from "diagram-js-minimap";
import paletteProvider from "@/components/Camunda/Bpmn/src/bpnm-utils/palette-provider";
import CustomContextPadProvider from "@/components/Camunda/Bpmn/src/bpnm-utils/custom-context-pad-provider";
//颜色
import bpmnColorPicker from "bpmn-js-color-picker";
//校验
//@ts-ignore
import bpmnlintModule from "bpmn-js-bpmnlint";
// 标签解析 Moddle
import camundaModdleDescriptor from "./plugins/descriptor/camundaDescriptor.json";
// 标签解析 Extension
import camundaModdleExtension from "./plugins/extension-moddle/camunda";
import type { CSSProperties } from "vue";
import { VAceEditor } from "vue3-ace-editor";
import "@/config/aceConfig";
import type { Ace } from "ace-builds";
import Panel from "./PropertyPanel.vue";
import { get } from "lodash-es";
import systask from "@/api/wms-system/systask";
import { useBpmnStore } from "@/stores/bpmn";

const bpmnPainStore = useBpmnStore();
const headerStyle: CSSProperties = reactive({
  color: "#555",
  height: 30,
  marginBottom: 10,
  lineHeight: "30px",
  backgroundColor: "#ffffff",
});
const contentStyle: CSSProperties = reactive({
  color: "#555",
  backgroundColor: "#fbfbfb",
});
const emits = defineEmits(["result", "close"]);
const props = defineProps({
  simulation: {
    type: Boolean,
    default: true,
  },
  xml: {
    type: String,
    default: "",
  },
  users: {
    type: Array,
    default: () => [],
  },
  roles: {
    type: Array,
    default: () => [],
  },
  groups: {
    type: Array,
    default: () => [],
  },
  categorys: {
    type: Array,
    default: () => [],
  },
  isView: {
    type: Boolean,
    default: false,
  },
  bpmnID: {
    type: String,
    default: "modeler-container",
  },
  isReadOnly: {
    type: Boolean,
    default: false,
  },
  options: {
    type: Object,
    default: () => {},
  },
  keyboard: {
    type: Boolean,
    default: true,
  },
  processId: {
    type: String,
    default: "",
  },
  processName: {
    type: String,
    default: "",
  },
  prefix: {
    type: String,
    default: "camunda",
  },
});
const modelerContainer = ref();
const zoom = ref<number>(1);
const xmlVisible = ref<boolean>(false);
const updatingProperties = ref<boolean>(false);
const revocable = ref<boolean>(false);
const recoverable = ref<boolean>(false);
const simulationStatus = ref<boolean>(false);

const xmlView = ref<string>("");
const type = ref<string>("");
const bpmnElementId = ref<string>("");
const businessObject: any = ref({});
const editorOptions: Partial<Ace.EditorOptions> = reactive({
  useWorker: true, // 启用语法检查,必须为true
  enableBasicAutocompletion: true, // 自动补全
  enableLiveAutocompletion: true, // 智能补全
  enableSnippets: true, // 启用代码段
  showPrintMargin: false, // 去掉灰色的线，printMarginColumn
  highlightActiveLine: false, // 高亮行
  highlightSelectedWord: true, // 高亮选中的字符
  tabSize: 4, // tab锁进字符
  fontSize: 14, // 设置字号
  wrap: true, // 是否换行
  readOnly: true, // 是否可编辑
  minLines: 1, // 最小行数，minLines和maxLines同时设置之后，可以不用给editor再设置高度
  maxLines: 50, // 最大行数
});
let bpmnStore: any = null;
let bpmnStoreElement: any = null;

const route = useRoute();
onMounted(() => {
  const Modules = [];
  const Extensions: Record<any, any> = {};
  // 根据需要的 "流程类型" 设置 对应的解析文件
  if (props.prefix === "camunda") {
    //@ts-ignore
    Modules.push(camundaModdleExtension);
    Extensions.camunda = camundaModdleDescriptor;
  }
  if (props.isReadOnly) {
    // 当组件处于只读模式时，初始化 BPMN 模型器，并配置为只读状态
    bpmnStore = new Modeler({
      container: `#${props.bpmnID}`, // 定义 BPMN 图表的容器
      additionalModules: [
        // 添加翻译
        {
          translate: ["value", translate()],
          paletteProvider: ["value", ""], // 禁用/清空左侧工具栏
          labelEditingProvider: ["value", ""], // 禁用节点编辑
          contextPadProvider: ["value", ""], // 禁用图形菜单
          bendpoints: ["value", {}], // 禁用连线拖动
          // zoomScroll: ['value', ''], // 禁用滚动
          // moveCanvas: ['value', ''], // 禁用拖动整个流程图
          move: ["value", ""], // 禁用单个图形拖动
        },
        GridLineModule, // 启用网格线模块
        bpmnColorPicker, //颜色模块
        bpmnlintModule, //校验模块
        ...Modules, // 扩展其他模块
      ],
      linting: {
        bpmnlint: lintConfig, // 传入规则配置
      },
      gridLine: {
        // 配置网格线样式
        smallGridSpacing: 20,
        gridSpacing: 80,
        gridLineStroke: 1,
        gridLineOpacity: 0.2,
        gridLineColor: "#ddd",
      },
      moddleExtensions: Extensions, // 扩展模型定义
      ...props.options, // 合并传入的自定义选项
    });
  } else {
    // 当组件不处于只读模式时，初始化 BPMN 模型器，并配置为可编辑状态
    bpmnStore = new Modeler({
      container: `#${props.bpmnID}`, // 定义 BPMN 图表的容器
      ...(props.keyboard ? { keyboard: {} } : {}), // 仅保留 keyboard 模块（如果需要）
      additionalModules: [
        // 添加翻译
        { translate: ["value", translate()] },
        paletteProvider, // 启用默认左侧工具栏
        CustomContextPadProvider, // 启用自定义图形菜单
        tokenSimulation, // 启用令牌模拟
        miniMapModule, // 启用小地图模块
        GridLineModule, // 启用网格线模块
        bpmnColorPicker, //颜色模块
        // bpmnlintModule,//校验模块
        ...Modules, // 扩展其他模块
      ],
      linting: {
        bpmnlint: lintConfig, // 传入规则配置
      },
      gridLine: {
        // 配置网格线样式
        smallGridSpacing: 15,
        gridSpacing: 60,
        gridLineStroke: 1,
        gridLineOpacity: 0.25,
        gridLineColor: "#ddd",
      },
      moddleExtensions: Extensions, // 扩展模型定义
      ...props.options, // 合并传入的自定义选项
    });
  }

  console.log(get(route, "query.key"));
  if (route?.query.key) {
    setDiagram();
  } else {
    newDiagram();
  }
  // if (!props.xml) {
  //   newDiagram();
  // } else {
  //   createNewDiagram(props.xml);
  // }
  // 监听图形改变返回xml
  bpmnStore.on("commandStack.changed", async () => {
    recoverable.value = bpmnStore.get("commandStack").canRedo();
    revocable.value = bpmnStore.get("commandStack").canUndo();
  });
  bpmnStore.on("root.added", (e: any) => {
    if (e.element.type) {
      console.log(e.element);
      bpmnStoreElement = e.element;
      type.value = getType(e.element);
      bpmnElementId.value = e.element.businessObject.id;
      businessObject.value = e.element.businessObject;
      console.log(e, type.value, "typeInfo");
    }
  });
  const isFirefox = navigator.userAgent.indexOf("Firefox") > -1; // 判断是否Firefox浏览器;
  const addEvent = (function () {
    return function (el: any, sType: any, fn: any, capture: any) {
      el.addEventListener(sType, fn, capture);
    };
  })();
  const stopEvent = function (event: any) {
    if (event.stopPropagation) {
      event.stopPropagation();
    } else {
      event.cancelBubble = true;
    }
    if (event.preventDefault) {
      event.preventDefault();
    } else {
      event.returnValue = false;
    }
  };
  const mousewheel = isFirefox ? "DOMMouseScroll" : "mousewheel";

  addEvent(
    modelerContainer.value,
    mousewheel,
    function (event: any) {
      const e = event || window.event;
      event.preventDefault();
      stopEvent(e);
    },
    false
  );
});

const setDiagram = async () => {
  const { backData, result } = await systask.detailFlow({
    id: get(route, "query.key"),
  })();
  if (result) {
    bpmnPainStore.$patch({ bpmnBase: backData.data });
    // const processId = props.processId || `${new Date().getTime()}`;
    // const processName = props.processName || `业务流程_${new Date().getTime()}`;
    createNewDiagram(
      get(backData, "data.content")
      // createDefaultEmptyXml(
      //   get(backData, "data.code"),
      //   get(backData, "data.name"),
      //   get(backData, "data.content")
      // )
    );
  } else {
    newDiagram()
  }
  // console.log(backData.data, result);
};

const EVENT_TYPE = ["element.click", "shape.added", "element.changed"];
// 添加绑定事件
const addBpmnListener = () => {
  if (props.isReadOnly) {
    return;
  }
  EVENT_TYPE.forEach((typeItem) => {
    bpmnStore.on(typeItem, (e: any) => {
      if (typeItem === "root.added" && !e.element.type) return;
      if (!e.element) {
        return;
      }
      if (e.element.type == "label" && typeItem == "shape.added") {
        return;
      }
      //当前上下文中更新属性 触发element.changed直接过  不刷新业务对象 防止属性表单丢失焦点
      const updating = updatingProperties.value;
      //当触发element.changed事件 需要判断改变的类型是否与当前选中的一样  一样才刷新
      const elementTypeNonEqualActive =
        e.element && e.element.id !== bpmnStoreElement?.id;
      console.log(
        updating,
        elementTypeNonEqualActive,
        e.element.type,
        "1111111111"
      );
      if (
        "element.changed" === typeItem &&
        (updating || elementTypeNonEqualActive)
      ) {
        return;
      }
      nextTick(() => {
        if (
          typeItem === "shape.added" &&
          [
            "bpmn:StartEvent",
            "bpmn:EndEvent",
            "bpmn:UserTask",
            "bpmn:Process",
          ].includes(e.element.type) &&
          !e.element.businessObject.name
        ) {
          // 当添加节点到编辑区 节点的name不存在时 初始化名称
          if (e.element.type == "bpmn:StartEvent") {
            updateProperties(e.element, {
              name: "开始",
            });
          }
          if (e.element.type == "bpmn:EndEvent") {
            updateProperties(e.element, {
              name: "结束",
            });
          } else if (e.element.type == "bpmn:UserTask") {
            updateProperties(e.element, {
              name: "任务",
            });
          } else if (e.element.type == "bpmn:Process") {
            updateProperties(e.element, {
              name: "",
            });
          }
          // else if (e.element.type == 'bpmn:ExclusiveGateway') {
          //   updateProperties(e.element, {
          //     name: '互斥网关'
          //   })
          // }
        }
        // 更新当前选中节点信息
        bpmnStoreElement = e.element;
        type.value = getType(e.element);
        bpmnElementId.value = e.element.businessObject.id;
        businessObject.value = e.element.businessObject;

        console.log('object',e.element.businessObject);
        console.log(e, type.value, typeItem, "typeInfo");
      });
    });
  });
};

const getType = (element: any) => {
  let type = "";
  type = element?.businessObject?.$type;
  return type;
};
const toSave = () => {
  saveDiagram((err: any, xml: string) => {
    // console.log(err)
    emits("result", {
      xml: xml,
    });
  });
};
function cancel() {
  emits("close");
}
const saveDiagram = async (done: any) => {
  // 把传入的done再传给bpmn原型的saveXML函数调用
  const { err, xml } = await bpmnStore.saveXML({ format: true });
  done(err, xml);
};

// 初始化流程
const newDiagram = () => {
  const processId = props.processId || `${new Date().getTime()}`;
  // const processId = props.processId || `Process_${new Date().getTime()}`
  const processName = props.processName || `业务流程_${new Date().getTime()}`;
  createNewDiagram(createDefaultEmptyXml(processId, processName, props.prefix));
  // createNewDiagram(defaultEseyBpmnXml(processId, processName, props.prefix))
  // createNewDiagram(createDefaultBpmnXml(processId, processName, props.prefix))
};
const createNewDiagram = (xml?: string | null) => {
  return new Promise<void>((resolve, reject) => {
    try {
      bpmnStore
        .importXML(xml)
        .then((result: any) => {
          addBpmnListener();
          if (result.length) {
            // 居中
            reset();
          }
          resolve();
        })
        .catch((err: any) => {
          reject();
          console.warn("importFail errors ", err);
        });
    } catch (err: any) {
      reject();
      console.error(err.message, err.warnings);
    }
  });
};

//更新节点数据
/**
 * 批量更新BPMN元素属性（带状态锁定的安全更新）
 * @param element - 需要更新的BPMN元素对象，通常来自bpmn-js的元素实例
 * @param properties - 要更新的属性映射对象，键为属性名，值为属性值
 * @returns void 无返回值
 */
const updateProperties = (element: any, properties: PropertiesMap<any>) => {
  // 开始更新前设置锁定状态，防止重复更新/冲突更新
  updatingProperties.value = true;

  // 调用BPMN建模模块进行实际属性更新
  // 该方法将批量应用属性到指定元素
  bpmnStore.get("modeling").updateProperties(element, properties);

  // 更新完成后解除锁定状态
  updatingProperties.value = false;
};

//获取当前节点
const bpmnElement = () => {
  return bpmnStoreElement;
};
//获取bpmn示例
/**
 * 获取BPMN建模工具相关实例集合的工厂函数
 *
 * 该函数集中暴露bpmn-js核心模块实例，用于在Vue组件中快速访问BPMN建模工具的各种服务模块。
 * 通过bpmnStore统一获取各模块实例，避免重复调用get方法。
 *
 * @returns {Object} 包含BPMN建模工具核心模块的对象:
 * @returns {Object} modeler - BPMN建模器主实例
 * @returns {Object} modeling - 模型操作模块，提供元素创建/删除等基础操作
 * @returns {Object} moddle - BPMN元模型处理模块，用于处理BPMN元模型实例
 * @returns {Object} eventBus - 事件总线模块，用于监听/触发建模事件
 * @returns {Object} bpmnFactory - BPMN元素工厂，负责创建BPMN元素实例
 * @returns {Object} elementFactory - 图形元素工厂，用于创建图形元素
 * @returns {Object} elementRegistry - 元素注册表，存储所有画布元素引用
 * @returns {Object} replace - 元素替换模块，提供元素替换功能
 * @returns {Object} selection - 选中管理模块，管理画布选中状态
 */
const bpmnInstances: any = () => {
  return {
    modeler: bpmnStore,
    modeling: bpmnStore.get("modeling"),
    moddle: bpmnStore.get("moddle"),
    eventBus: bpmnStore.get("eventBus"),
    bpmnFactory: bpmnStore.get("bpmnFactory"),
    elementFactory: bpmnStore.get("elementFactory"),
    elementRegistry: bpmnStore.get("elementRegistry"),
    replace: bpmnStore.get("replace"),
    selection: bpmnStore.get("selection"),
  };
};
// 使用provide提供函数
provide("updateProperties", updateProperties);
provide("bpmnElement", bpmnElement);
provide("bpmnInstances", bpmnInstances);
provide("prefix", props.prefix);

onBeforeUnmount(() => {
  bpmnStore = null;
});

const getXML = () => {
  return new Promise((resolve, reject) => {
    bpmnStore
      .saveXML({ format: true })
      .then((response: { xml: string }) => {
        console.log('response');
        resolve(response);
      })
      .catch((err: unknown) => {
        console.log('err');
        reject(err);
      });
  });
};
const preView = async () => {
  xmlVisible.value = true;
  try {
    // eslint-disable-next-line no-unsafe-optional-chaining
    const { xml }: any = await getXML();
    xmlView.value = xml;
  } catch (err) {
    console.log(err);
  }
};
// 导入XML
const importXML = () => {
  const fileUpload: any = document.createElement("input");
  fileUpload.type = "file";
  fileUpload.click();
  fileUpload.onchange = () => {
    const file = fileUpload.files[0];
    const reader = new FileReader();
    reader.onload = () => {
      const xml: any = reader.result;
      bpmnStore.importXML(xml);
    };
    reader.readAsText(file);
  };
};

const processRedo = () => {
  bpmnStore.get("commandStack").redo();
};
const processUndo = () => {
  bpmnStore.get("commandStack").undo();
};
const processRestart = () => {
  recoverable.value = false;
  revocable.value = false;
  const processId = props.processId || `Process_${new Date().getTime()}`;
  const processName = props.processName || `业务流程_${new Date().getTime()}`;
  createNewDiagram(
    createDefaultEmptyXml(processId, processName, props.prefix)
  ).then(() => {
    reset();
  });
};

const processSimulation = () => {
  simulationStatus.value = !simulationStatus.value;
  props.simulation && bpmnStore.get("toggleMode").toggleMode();
};
// 放大
const moreBig = () => {
  zoom.value = Math.floor(zoom.value * 100 + 0.1 * 100) / 100;
  bpmnStore.get("canvas").zoom(zoom.value);
};
// 缩小
const moreSmall = () => {
  zoom.value = Math.floor(zoom.value * 100 - 0.1 * 100) / 100;
  bpmnStore.get("canvas").zoom(zoom.value);
};
// 缩小
const reset = () => {
  zoom.value = 1;
  bpmnStore.get("canvas").zoom("fit-viewport", "auto");
};

// 导出XML
const exportXML = () => {
  const rootElement = bpmnStore.get("canvas").getRootElement();
  getXML()
    .then((response: any) => {
      download(response.xml, rootElement.id || "process", "bpmn");
    })
    .catch((err: unknown) => {
      console.warn(err);
    });
};
// 导出SVG
const getSVG = () => {
  return new Promise((resolve, reject) => {
    bpmnStore
      .saveSVG()
      .then((response: { svg: string }) => {
        resolve(response);
      })
      .catch((err: unknown) => {
        reject(err);
      });
  });
};
const showHideMap = () => {
  bpmnStore.get("minimap").toggle();
};
const exportSVG = () => {
  const rootElement = bpmnStore.get("canvas").getRootElement();
  getSVG()
    .then((response: any) => {
      download(response.svg, rootElement.id || "process", "svg");
    })
    .catch((err: unknown) => {
      console.warn(err);
    });
};

//文本下载
const download = (data: string, filename: string, type: string): void => {
  const blob = new Blob([data]);
  const tempLink = document.createElement("a"); // 创建a标签
  const href = window.URL.createObjectURL(blob); // 创建下载的链接
  //filename
  const fileName = `${filename}.${type}`;
  tempLink.href = href;
  tempLink.target = "_blank";
  tempLink.download = fileName;
  document.body.appendChild(tempLink);
  tempLink.click(); // 点击下载
  document.body.removeChild(tempLink); // 下载完成移除元素
  window.URL.revokeObjectURL(href); // 释放掉blob对象
};
</script>
<style>
.full-modal {
  .ant-modal {
    max-width: 100%;
    top: 0;
    padding-bottom: 0;
    margin: 0;
  }
  .ant-modal-content {
    display: flex;
    flex-direction: column;
    height: calc(100vh);
  }
  .ant-modal-body {
    flex: 1;
  }
}
</style>
<style lang="less" scoped>
.w100 {
  width: 100%;
}
.h100 {
  height: 100%;
}
:deep(.ant-layout .ant-layout-header) {
  height: 30px;
}
.cav-container {
  height: calc(100% - 31px);
  .canvas {
    width: 100%;
    height: 100%;
  }
}
:deep(.ant-layout-sider) {
  flex: 0 0 350px !important;
  max-width: 350px !important;
  min-width: 350px !important;
  width: 350px !important;
  background: #ffffff !important;
  border-left: 1px solid #f1f1f1;
  overflow-y: auto;
}
.vue-ace-editor {
  width: 98%;
  font-size: 16px;
  border: 1px solid;
}

.bpmn-page {
  width: 100%;
  height: 100%;
  position: relative;
}

.bjs-powered-by {
  display: none;
}

.bpmn-container {
  height: 100%;
}

.modeler-container {
  position: relative;
  flex: 1;
  height: 100%;
  // background: url('')
  //   repeat !important;
}

.djs-palette {
  top: 65px !important;
  border: none !important;
  background-color: #fff !important;
  box-shadow: 0 3px 3px rgb(0 0 0 / 20%);
}

:deep(.djs-palette.two-column.open) {
  width: 100px !important;
}

.icon-custom {
  /* 定义一个公共的类名 */
  border-radius: 50%;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 65%;
}

:deep(.icon-custom.lindaidai-task) {
  width: 30px;
  height: 30px;
  margin: 8px;

  /* 加上背景图 */
  background: url("https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/rules.png")
    no-repeat;
  background-size: 100% 100%;
}

:deep(.djs-context-pad) .lindaidai-task.entry:hover {
  background: url("https://hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/rules.png")
    no-repeat;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 95%;
}

:deep(.djs-context-pad) .entry:hover {
  /* 重新修改了 hover 之后的样式 */

  /* border: 1px solid #1890ff; */
  box-sizing: border-box;
}

:deep(.djs-context-pad) .entry {
  box-sizing: border-box;
  transition: all 0.3s;
  background-size: 94%;
}

.default-input {
  margin-bottom: 10px;
}

.bpmn-operation {
  position: absolute;
  bottom: 2%;
  left: 1%;
  display: flex;
  justify-content: space-evenly;
  align-items: center;

  svg {
    width: 30px;
    height: 30px;
    margin-right: 16px;
    cursor: pointer;
  }
  // background-color: red;
}
:deep(a.bjs-powered-by) {
  display: none;
}
:deep(.bts-toggle-mode) {
  display: none;
}
:deep(.djs-palette) {
  background: #f1f1f1;
  border: solid 1px #ddd !important;
  border-radius: 5px;
}
//侧边栏配置
:deep(.djs-palette.open) {
  .djs-palette-entries {
    div[class^="bpmn-icon-"]:before,
    div[class*="bpmn-icon-"]:before {
      line-height: unset;
    }
    div.entry {
      position: relative;
    }
    div.entry:hover {
      &::after {
        width: max-content;
        content: attr(title);
        vertical-align: text-bottom;
        position: absolute;
        right: -10px;
        top: 0;
        bottom: 0;
        overflow: hidden;
        transform: translateX(100%);
        font-size: 0.5em;
        display: inline-block;
        text-decoration: inherit;
        font-variant: normal;
        text-transform: none;
        background: #fafafa;
        box-shadow: 0 0 6px #eeeeee;
        border: 1px solid #cccccc;
        box-sizing: border-box;
        padding: 0 16px;
        border-radius: 4px;
        z-index: 100;
      }
    }
  }
}
:deep(.djs-palette.open) {
  width: 94px !important;
}
:deep(.djs-popup-backdrop) {
  position: absolute;
  width: 100%;
  height: 100%;
}
:deep(.djs-popup-group) li[data-id^="replace-with-message-intermediate-throw"],
:deep(.djs-popup-group) li[data-id^="replace-with-message-intermediate-catch"],
:deep(.djs-popup-group)
  li[data-id^="replace-with-escalation-intermediate-throw"],
:deep(.djs-popup-group)
  li[data-id^="replace-with-conditional-intermediate-catch"],
:deep(.djs-popup-group) li[data-id^="replace-with-link-intermediate-throw"],
:deep(.djs-popup-group) li[data-id^="replace-with-link-intermediate-catch"],
:deep(.djs-popup-group)
  li[data-id^="replace-with-compensation-intermediate-throw"],
:deep(.djs-popup-group)
  li[data-id^="replace-with-compensation-intermediate-catch"],
:deep(.djs-popup-group) li[data-id^="replace-with-signal-intermediate-throw"],
:deep(.djs-popup-group) li[data-id^="replace-with-signal-intermediate-catch"] {
  display: none;
}
:deep(.djs-minimap) {
  top: auto;
  bottom: 20px !important;
  .toggle {
    display: none;
  }
}
</style>
